Skip to content

feat: chiselled rocks build for bread flavours#4

Open
lczyk wants to merge 18 commits into
mainfrom
rocks
Open

feat: chiselled rocks build for bread flavours#4
lczyk wants to merge 18 commits into
mainfrom
rocks

Conversation

@lczyk

@lczyk lczyk commented Jun 1, 2026

Copy link
Copy Markdown
Owner

parallel rocks/ tree migrating both flavours (bread, bread-chisel-releases) x {24.04,25.10,26.04} to rockcraft. base bare + build-base ubuntu@, built from chisel slices; sshd runs as a pebble service. the bread rock is the spread test-host itself, so allocate docker-runs the loaded rock directly.

tests live only in top-level rocks/tests/ (one flavour-branching contract task over 12 systems). rocks-ci.yaml builds per-arch + runs the suite; no publishing. existing docker-image world untouched (ci.yaml ignores rocks/**).

known holes: tree + skopeo have no slice yet (omitted from the cr flavour); pam is permit-only.

@lczyk

lczyk commented Jun 2, 2026

Copy link
Copy Markdown
Owner Author

lczyk added 18 commits July 20, 2026 08:00
parallel rocks/ tree migrating both flavours (bread, bread-chisel-releases)
x {24.04,25.10,26.04} to rockcraft. base bare + build-base ubuntu@<ver>,
built from chisel slices; sshd runs as a pebble service. the bread rock is
the spread test-host itself, so allocate docker-runs the loaded rock directly.

tests live only in top-level rocks/tests/ (one flavour-branching contract
task over 12 systems). rocks-ci.yaml builds per-arch + runs the suite; no
publishing. existing docker-image world untouched (ci.yaml ignores rocks/**).

known holes: tree + skopeo have no slice yet (omitted from the cr flavour);
pam is permit-only.
rockcraft's stage-packages slice cut has no retry, so a single intermittent
"expected digest ..." from the chisel-releases archive failed the whole pack
(seen in rocks CI). drop stage-packages; chisel-cut the slices ourselves in
override-build (clone chisel-releases @ ubuntu-<ver>, cut via chisel_cut.sh
which retries 10x on the known archive flakes). pattern from not-quite-rust-rock.

cr flavour folds its tooling slices into the same single cut.
iproute2_ip-bin doesn't exist on the ubuntu-24.04/25.10 chisel-releases
branches (only the unified iproute2_bins, which ships ip); on 26.04
iproute2_bins pulls ip-bin transitively. so iproute2_bins resolves ip on all
three. unblocks the bread-chisel-releases rock pack.
spread finds tasks as <suite>/<task>/task.yaml; the contract task sat directly
at contract/task.yaml, so no jobs existed and the filter matched nothing. move
it to contract/run/task.yaml.
the rock has no grep (coreutils_bins doesn't ship it), so the contract task
aborted at the banner check; rewrite it to use shell case instead of grep/sed.

allocate: bound the sshd wait to 60s and, on timeout, dump docker logs +
sshd -t + the sshd bits, then fail fast -- so a rock whose sshd never starts
(25.10/26.04) surfaces the cause instead of spinning to the kill-timeout.
banner: source the profile.d script directly instead of via a login shell -- a
chiselled rock's login shell doesn't source /etc/profile -> profile.d (separate
cosmetic hole), so the login-shell path gave empty output. assert the files are
installed and the script prints the banner when sourced.

allocate: gate readiness on an actual TCP connect to port 22 rather than pgrep
sshd -- a process can exist without listening, which false-readied 25.10/26.04
and spun spread to the kill-timeout. on timeout, dump docker logs plus sshd -t
plus the sshd bits so a non-listening sshd surfaces its cause.
OpenSSH >=9.8 (25.10, 26.04) re-execs sshd-session (and sshd-auth) per
connection; the chisel-releases openssh-server slice lists only /usr/sbin/sshd,
so sshd exits 255 at startup and never listens. patch the cloned slice (sed) to
add both binaries before cutting -- only on the newer series; 24.04 ships
OpenSSH 9.6 which predates the split and has no such binaries.
the session shell already sources /etc/profile -> profile.d, whose silent
non-tty path exports BREAD_BANNER_SHOWN=1. so the contract's re-source hit the
dedupe guard and printed nothing. clear the var in the check so the banner
actually re-prints.
the hack scripts + chisel patches were copied into every rock dir. move them to
a single source of truth (rocks/hack, rocks/patches) and regenerate each rock's
own copy from there via rocks/sync_shared.rb -- rockcraft only copies the
project dir into the build, so each rock still needs its physical copy at pack
time, but it's no longer hand-maintained in 6 places.

per-dir hack/ + patches/ are now gitignored + synced. the per-dir makefiles run
the sync before packing (.rock.stamp depends on it); the ci build job runs it
before rockcraft-pack. byte-identical output, so rocks build/test unchanged.
swap the rocks build job's rockcraft-pack from canonical/craft-actions@main to
the fork branch in canonical/craft-actions#59 (node24 migration), to clear the
node20 deprecation warning. revert to canonical@main once that PR merges.
the chisel patches duplicated the repo-root patches/chisel (used by the
docker-image build). sync_shared.rb now copies them from there into each cr
rock dir, and rocks/patches is removed.
…kefiles

fold the per-dir build recipe into one build-% pattern rule in rocks/makefile
(sync shared files -> stamp short-circuit -> rockcraft pack -> rename to
<dir>.rock) and remove the six per-dir makefiles. each rock dir is now just
rockcraft.yaml + the synced hack/ (+ patches/ for the cr flavour). ci is
unaffected -- the build job uses the rockcraft-pack action, the test job uses
make spread-only.
move the rock contract into the top-level tests/spread.yaml as its own backend
(rock, docker-runs the loaded rock) + suite (contract-rocks), alongside the
docker-image suites. spread has no systems wildcards, so scope by name: the
bread-image suites whitelist the outer systems, contract-rocks excludes them.

workflows stay separate and each runs only its backend: the docker ci runs
spread outer:..., the rocks ci runs spread rock:... (via make spread-only,
now cd ../tests). rocks/tests/ is removed.
complete the coupling: add the rock backend + contract-rocks suite (with
name-based system scoping) to tests/spread.yaml, and repoint rocks/makefile's
test targets at ../tests. (the file moves landed in the previous commit; the
add of these two was dropped by a stale pathspec.)
banner.txt, bread-warning.sh and lazy-apt.sh were byte-identical copies of the
repo-root hack/ ones. sync_shared.rb now pulls those three from repo-root hack/
(like the chisel patches), keeping only the rock-specific helpers (sshd-entry,
chisel_cut, the chisel/docker build scripts, and a rock-flavoured hash_inputs)
in rocks/hack. edit-once for the shared shim/banner logic.
complete the previous commit: sync_shared.rb now copies banner.txt,
bread-warning.sh and lazy-apt.sh from repo-root hack/ (the rock-hack copies were
removed there). the add of this file was dropped by a stale pathspec.
node24 migration (canonical/craft-actions#59) merged upstream, so drop the
fork-branch trial and point back at canonical/craft-actions/rockcraft-pack@main.
@lczyk lczyk reopened this Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant